#include "VSObject.h"
#include "VSStream.h"
#include "VSProperty.h"
#include "VSGraphicInclude.h"
using namespace VSEngine2;
IMPLEMENT_RTTI_NoParent_NoCreateFun(VSObject)
unsigned int VSObject::ms_uiObjectNum = 0;
VSMapOrder<VSUsedName,FactoryFunction> VSObject::ms_ClassFactory;
VSArray<VSObject *> VSObject::ms_ObjectArray;
VSMap<VSObject *,VSObject *>	VSObject::ms_CloneMap;
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_BEGIN(VSObject)
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_END
BEGIN_ADD_PROPERTY_ROOT(VSObject)
//REGISTER_PROPERTY(m_bEnable,Enable);
END_ADD_PROPERTY

VSObject* VSObject::CloneCreateObject(VSObject * pObject)
{
	ms_CloneMap.Clear();
	return _CloneCreateObject(pObject);
}
void VSObject::CloneObject(VSObject * pObjectSrc,VSObject * pObjectDest)
{
	ms_CloneMap.Clear();
	_CloneObject(pObjectSrc,pObjectDest);
}
VSObject* VSObject::_CloneCreateObject(VSObject * pObject)
{
	unsigned int uiIndex = ms_CloneMap.Find(pObject);
	VSObject* pNewObject = NULL;
	if (uiIndex == ms_CloneMap.GetNum())
	{
		VSRtti & SrcRtti = pObject->GetType();
		pNewObject = VSObject::GetInstance(SrcRtti.GetName());
		ms_CloneMap.AddElement(pObject,pNewObject);
		VSRtti & DestRtti = pNewObject->GetType();

		for (unsigned int i = 0 ; i < SrcRtti.GetPropertyNum() ; i++)
		{
			VSProperty * pProperty = SrcRtti.GetProperty(i);
			if (pProperty->GetFlag() & VSProperty::F_CLONE)
			{
				pProperty->CloneData(pObject,pNewObject);
			}
			else if(pProperty->GetFlag() & VSProperty::F_COPY)
			{
				pProperty->CopyData(pObject,pNewObject);
			}

		}
		pNewObject->PostClone(pObject);
	}
	else
	{
		pNewObject = ms_CloneMap[uiIndex].Value;
	}
	return pNewObject;
}
void VSObject::_CloneObject(VSObject * pObjectSrc,VSObject * pObjectDest)
{
	VSRtti & SrcRtti = pObjectSrc->GetType();
	VSRtti & DestRtti = pObjectDest->GetType();
	for (unsigned int i = 0 ; i < SrcRtti.GetPropertyNum() ; i++)
	{
		VSProperty * pProperty = SrcRtti.GetProperty(i);
		pProperty->CloneData(pObjectSrc,pObjectDest);
	}
	pObjectDest->PostClone(pObjectSrc);
}
/********************************************************************************/
VSObject * VSObject::GetInstance(const VSString& sRttiName)
{
	unsigned int i = ms_ClassFactory.Find(sRttiName);
	if(i == ms_ClassFactory.GetNum())
		return NULL;

	return ms_ClassFactory[i].Value();

}
VSObject * VSObject::GetInstance(const VSRtti& Rtti)
{
	return (Rtti.m_CreateFun)();
}
/********************************************************************************/
VSObject::VSObject()
{
#ifdef _DEBUG
	//ms_ObjectCS.Lock();
	ms_uiObjectNum++;
	
	ms_ObjectArray.AddElement(this);
	//ms_ObjectCS.Unlock();
#endif	
}//end construct

/********************************************************************************/

VSObject::~VSObject()
{
#ifdef _DEBUG
	//ms_ObjectCS.Lock();
	for (unsigned int i = 0 ;i  < ms_ObjectArray.GetNum() ; i++)
	{
		if (ms_ObjectArray[i] == this)
		{
			ms_ObjectArray.Erase(i);
			break;
		}
	}
	//ms_ObjectCS.Unlock();
#endif
	
	


}//end destruct
/********************************************************************************/
// void VSObject::AddLink(VSObject *pObject)
// {
// 	m_Linker.AddElement(pObject);
// 
// }
/********************************************************************************/
// VSObject *VSObject::GetNextLink()
// {
// 	if(m_uiCurLink < m_Linker.GetNum())
// 	{
// 		VSObject * pTemp = m_Linker[m_uiCurLink];
// 		m_uiCurLink++;
// 		return pTemp;
// 	}
// 	else
// 		return NULL;
// }
/********************************************************************************/
// void VSObject::ClearLinker()
// {
// 	m_Linker.Clear();
// 	m_uiCurLink = 0;
// }
/********************************************************************************/
// void VSObject::DestroyLinker()
// {
// 	m_Linker.Destroy();
// 	m_uiCurLink = 0;
// }
/********************************************************************************/

bool VSObject::IsSameType(const VSObject *pObject)const
{

	return pObject && GetType().IsSameType(pObject->GetType());

}//end IsSameType

/********************************************************************************/

bool VSObject::IsDerived(const VSObject *pObject)const
{
	return pObject && GetType().IsDerived(pObject->GetType());
}//IsDerived

/********************************************************************************/

bool VSObject::IsSameType(const VSRtti &Type)const
{
	
	return GetType().IsSameType(Type);
}//IsSameType

/********************************************************************************/

bool VSObject::IsDerived(const VSRtti &Type)const
{
	return GetType().IsDerived(Type);
	
}//IsDerived
/********************************************************************************/
unsigned int  VSObject::DiskUse()const 
{
	unsigned int uiDistUse = 0;

	
	return uiDistUse;

}
/********************************************************************************/
bool VSObject::Clone(const VSObject * pObject,unsigned int uiType)
{
	

	if(!pObject)
		return 0;
	

	return 1;	
	

}
void VSObject::LoadedEvent()
{

}
/********************************************************************************/
bool VSObject::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	
	
	
	return 1;
}
/********************************************************************************/
bool VSObject::Load(VSStream & rStream,unsigned int &iSaveUse)
{


	
	return 1;
}
/********************************************************************************/
bool VSObject::Link(VSStream & rStream)
{
	return 1;
}
/********************************************************************************/
bool VSObject::Register(VSStream & rStream)const
{
	if (rStream.IsObjectRegister(this))
	{
		return 1;
	}
	if(!RegisterSelf(rStream))
		return 0;
	return 1;
}
/********************************************************************************/
bool VSObject::RegisterSelf(VSStream & rStream)const
{
	return true;
	//return rStream.RegisterObject(this);
}
bool VSObject::BeforeSave( void * pDate)
{
	return 1;
}
bool VSObject::PostLoad( void * pDate)
{
	return 1;
}
bool VSObject::PostClone(VSObject * pObjectSrc)
{
	return 1;
}
void VSObject::ValueChange(VSString & Name)
{

}